 page
*
*
findfile jsr lookfile ;see if file exists
 bcs nofind ;branch if an error was encountered
moventry ldy h.entln ;move entire entry info to a safe area
movent1 lda (drbufpl),y
 sta dfil+d.stor,y
 dey
 bpl movent1
 lda #0 ;to indicate all is well
nofind rts ;return condition codes.
 page
*
lookfile jsr preproot ;find volume and set up other boring stuff
 bcs fnderr ;pass back any error encountered
 bne lookfil0 ;branch if more than root.
 lda #<gbuf ; otherwise, report a badpath error
 sta drbufph ;(but first create a phantom entry for open)
 lda #4
 sta drbufpl
 ldy #d.auxid ;first move in id, and date stuff.
phantm1 lda (drbufpl),y
 sta dfil,y
 dey
 cpy #d.credt-1 
 bne phantm1
phantm2 lda rootstuf-d.filid,y
 sta dfil,y
 dey
 cpy #d.filid-1
 bne phantm2
 lda #dirtyp*$10 ;fake directory file
 sta dfil+d.stor
 lda #badpath ;(carry is set)
 rts
*
*
lookfil0 lda #0 ;reset free entry indicator
 sta nofree
 sec ;indicate that the directory to be searched has header in this block
lookfil1 lda #0 ;reset entry counter
 sta totent
 jsr looknam ;look for name pointed to by pnptr  
 bcc namfound ;branch if name was found.
 lda entcntl ;have we looked at all of the
 sbc totent ; entries in this directory?
 bcc dcrenth ;maybe, check hi count.
 bne lookfil2 ;no, read next directory block
 cmp entcnth ;has the last entry been looked at (acc=0)
 beq errfnf ;yes, give 'file not found' error.
 bne lookfil2 ;branch always.
dcrenth dec entcnth ;should be at least 1
 bpl lookfil2 ;(this should be branch always...)
errdir lda #direrr ;report directory messed up.
fnderr sec ;indicate error has been encountered.
 rts
*
 page
lookfil2 sta entcntl ;keep running count
 lda #<gbuf ;reset indirect pointer
 sta drbufph
 lda gbuf+2 ;get link to next directory block
 bne nxtdir0 ;(if there is one)
 cmp gbuf+3 ;are both zero, i.e. no link?
 beq errdir ;if so, then not all entries were accounted for.
nxtdir0 equ * ;acc has value for block # (low)
 ldx gbuf+3
 jsr rdblk ;go read the next linked directory in.
 bcc lookfil1 ;branch if no error.
 rts ;return error (in accumulator).
*
*
errfnf lda nofree ;was any free entry found?
 bne fnf0
 lda gbuf+2 ;test link
 bne telfree
 cmp gbuf+3 ;if both are zero, then give up
 beq fnf0 ; simply report 'not found'
telfree sta d.entblk
 lda gbuf+3
 sta d.entblk+1 ;assume first entry of next block
 lda #1 ; is free for use.
 sta d.entnum
 sta nofree ; mark d.entnum as valid (for create)
fnf0 jsr nxtpnam1 ;test for 'file not found' versus 'path not found'
errpath1 sec ;if non-zero then 'path not found'.
 beq fnf1
 lda #pathnotfnd ;report no such path.
 rts
fnf1 lda #fnferr ;report file not found.
 rts
 page
*
namfound jsr nxtpname ;adjust index to next name in path. 
 beq filfound ;branch if that was last name. 
 ldy #d.stor ;be sure this is a directory entry
 lda (drbufpl),y ;high nibble will tell
 and #$f0
 cmp #dirtyp*16 ;is it a sub-directory?
 bne errpath1 ;report the user's mistake
 ldy #d.frst ;get address of first sub-directory block
 lda (drbufpl),y
 sta bloknml ;(no checking is done here for a valid
 iny ; block number... )
 sta d.head ;save as file's header block too.
 lda (drbufpl),y
 sta bloknmh
 sta d.head+1
 jsr rdgbuf ;read sub-directory into gbuf
 bcs fnderr1 ;return immediately any error encountered.
 lda gbuf+hcent+4 ;get the number of files
 sta entcntl ; contained in this directory
 lda gbuf+hcent+5
 sta entcnth
 lda gbuf+hcmp+4 ;test backward compatability
 bne errcomp ;if not, don't proceed
 lda gbuf+hpenab+4 ;make sure password disabled
 ldx #0
 sec
 rol a
tstpas0 bcc tstpas1
 inx
tstpas1 asl a
 bne tstpas0
 cpx #5 ;is password disabled?
 beq movhead
*
errcomp lda #cpterr ;tell them this directory is not compatable
fnderr1 sec
 rts
*
movhead jsr movhed0 ;move info about this directory
 jmp lookfil0 ;do next local pathname
*
movhed0 ldx #$a ;move info about this directory
movhed1 lda gbuf+hcrdt+4,x
 sta h.credt,x
 dex
 bpl movhed1
 lda gbuf+4 ;if this is root, then nothing to do.
 and #$f0
 eor #$f0 ;test header type.
 beq mvhed3 ;branch if root.
 ldx #3 ;otherwise, save owner info about this header.
mvhed2 lda gbuf+hrblk+4,x
 sta own.blok,x
 dex
 bpl mvhed2 
mvhed3 rts
*
 page
*
*
filfound equ *
entadr lda h.maxent ;figure out which is entry number this is.
 sec
 sbc cntent ;max entries - count entries + 1 = entry number
 adc #0 ;(carry is/was set)
 sta d.entnum
 lda bloknml
 sta d.entblk
 lda bloknmh ;and indicate block number of this directory.
 sta d.entblk+1
 clc
 rts
*
looknam lda h.maxent ;reset count of files per block
 sta cntent
 lda #<gbuf 
 sta drbufph
 lda #4
loknam1 sta drbufpl ;reset indirect pointer to gbuf
 bcs loknam2 ;branch if this block contains a header
 ldy #d.stor
 lda (drbufpl),y ;get length of name in directory
 bne isname ;branch if there is a name.
 lda nofree ;test to see if a free entry has been declared.
 bne loknam2 ;yes bump to next entry
 jsr entadr ;set address for current entry
 inc nofree ;indicate a free spot has been found
 bne loknam2 ;branch always.
*
isname and #$f ;strip type (this is checked by 'filfound')
 inc totent ;(bump count of valid files found)
 sta namcnt ;save name length as counter
 ldx pnptr ;get index to current path.
 cmp pathbuf,x ;are both names of the same length?
 bne loknam2 ;no, bump to next entry
* 
cmpname inx ;(first) next letter index 
 iny
 lda (drbufpl),y ;compare names letter by letter
 cmp pathbuf,x 
 bne loknam2
 dec namcnt ;have all letters been compared?
 bne cmpname ;no, continue..
 clc ;by golly, we got us a match!
noname rts
*
loknam2 dec cntent ;have we checked all possible entries in this block?
 sec
 beq noname ;yes, give up.
 lda h.entln ;add entry length to current pointer
 clc
 adc drbufpl
 bcc loknam1 ;branch if we're still in the first page.
 inc drbufph ;look on second page
 clc ;carry should always be clear before looking at next.
 bcc loknam1 ;branch always...
 page
